home *** CD-ROM | disk | FTP | other *** search
- Path: taco.cc.ncsu.edu!news
- From: Scott Mebust <samebust@pop-in.ncsu.edu>
- Newsgroups: comp.lang.c++
- Subject: Embedded classes in Class Templates
- Date: 24 Mar 1996 18:53:20 GMT
- Organization: North Carolina State University
- Message-ID: <4j45n0$ck7@taco.cc.ncsu.edu>
- NNTP-Posting-Host: s013h011.dialup.ncsu.edu
- Mime-Version: 1.0
- Content-Type: text/plain; charset=us-ascii
- Content-Transfer-Encoding: 7bit
- X-Mailer: Mozilla 1.22 (Windows; U; 16bit)
-
- RE: Template Class Nested Types: Private member functions of the
- enclosing class that take parameters of the enclosed class type.
-
- (Damn the terminology! Fool speed ahead!)
-
-
- I've got a question concerning "Template Class Nested Types" (as Lippman
- refers to them in his C++ Primer, 2nd Edition). Trying my hand at
- creating some generic dynamic data types (container classes) in C++ using
- templates, I've had some success. (I know, I know, with STL around, why
- should one bother? A: To learn.) I've implemented the standard Stack
- and Queue, and they were both easy to "templatize". In my Queue class
- template, I declared a Node class within the private section of the Queue
- class declaration. This worked out well. I have since coded a binary
- tree class with a similarly nested Node class. The non-templatized
- version of this class compiled without error and worked well. However,
- when I attempted to convert the class to a class template, I ran into a
- problem. In a nutshell, some of the private member functions of the
- Binary Tree class take a reference to a pointer to a Node as a parameter.
- The declarations of these member functions cause no problems but the
- definitions of the member functions, which are outside of the class
- declaration, cause the compilers (GNU 2.7.0(?) under Linux,
- Borland C++ 3.1) to choke. They apparently don't recognize the Node
- class (that is, it appears to be out of scope). But, if I move the body
- of these member functions into the Binary Tree class declaration (inline),
- the compilers happily accept the code. I have tried qualifying the
- Node class with the Tree class name and template parameter list but this
- didn't help (i.e. tree<type>::node ).
-
- Q: What limitation am I running up against? What is my misunderstanding?
-
- I've included "complete" code snippets below that demonstrate the problem.
- The first snippet is a non-template integer binary tree that compiles fine.
- The second snippet is a templatized binary tree class that bombs a couple
- of lines into the tree::Insert2 member function definition. The third
- snippet is a templatized version in which I've moved the body of the
- tree::Insert2 member function into the tree template class declaration
- (inline). The third snippet also compiles fine.
-
- Thanks in advance for any help with this problem. I've referenced
- Stroustrup, Lippman, and a couple of other books concerning this but to
- no avail.
-
- // SNIPPET 1 //
-
- #include <stddef.h>
-
- class inttree
- {
- public:
- inttree();
- void Insert(const int &i);
- //
- // other member functions like Delete, etc.
- //
-
- private:
- class node
- {
- public:
- int value_;
- node *lchild_, *rchild_;
- };
-
- void Insert2(const int &i, node* &np);
- //
- // other private member functions
- //
-
- node *root_;
- };
-
-
-
- inttree::inttree()
- {
- root_=NULL;
- }
-
-
- void inttree::Insert(const int &i)
- {
- Insert2(i, root_);
- }
-
-
- void inttree::Insert2(const int &i, node* &np)
- {
- if (np==NULL)
- {
- np=new node;
- // assert (np!=NULL);
- np->lchild_=NULL;
- np->rchild_=NULL;
- np->value_=i;
- }
- else if (i<np->value_)
- Insert2 (i,np->lchild_);
- else if (i>np->value_)
- Insert2 (i,np->rchild_);
- }
-
- // END SNIPPET 1 //
-
- // SNIPPET 2 //
-
- #include <stddef.h>
-
- template <class info>
- class tree
- {
- public:
- tree();
- void Insert(const info &i);
- //
- // other member functions like Delete, etc.
- //
-
- private:
- class node
- {
- public:
- info value_;
- node *lchild_, *rchild_;
- };
-
- void Insert2(const info &i, node* &np);
- //
- // other private member functions
- //
-
- node *root_;
- };
-
-
- template <class info>
- tree<info>::tree()
- {
- root_=NULL;
- }
-
- template <class info>
- void tree<info>::Insert(const info &i)
- {
- Insert2(i, root_);
- }
-
- template <class info>
- void tree<info>::Insert2(const info &i, node* &np)
- {
- if (np==NULL)
- {
- np=new node;
- // assert (np!=NULL);
- np->lchild_=NULL;
- np->rchild_=NULL;
- np->value_=i;
- }
- else if (i<np->value_)
- Insert2 (i,np->lchild_);
- else if (i>np->value_)
- Insert2 (i,np->rchild_);
- }
-
- // END SNIPPET 2 //
-
- // SNIPPET 3 //
-
- #include <stddef.h>
-
- template <class info>
- class tree
- {
- public:
- tree();
- void Insert(const info &i);
- //
- // other member functions like Delete, etc.
- //
-
- private:
- class node
- {
- public:
- info value_;
- node *lchild_, *rchild_;
- };
-
- void Insert2(const info &i, node* &np)
- {
- if (np==NULL)
- {
- np=new node;
- // assert (np!=NULL);
- np->lchild_=NULL;
- np->rchild_=NULL;
- np->value_=i;
- }
- else if (i<np->value_)
- Insert2 (i,np->lchild_);
- else if (i>np->value_)
- Insert2 (i,np->rchild_);
- }
- //
- // other private member functions
- //
-
- node *root_;
- };
-
-
- template <class info>
- tree<info>::tree()
- {
- root_=NULL;
- }
-
- template <class info>
- void tree<info>::Insert(const info &i)
- {
- Insert2(i, root_);
- }
-
- // END SNIPPET 3 //
-
-
-